package cn.com.surker.lab.controller;

import cn.com.surker.base.strength.entity.BaseStrength;
import cn.com.surker.base.strength.service.StrengthBaseService;
import cn.com.surker.base.system.entity.SysLine;
import cn.com.surker.common.AbstractController;
import cn.com.surker.common.MessageCenterException;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.lab.UploadTypeEnum;
import cn.com.surker.enums.material.SysMaterialTypeEnum;
import cn.com.surker.enums.production.indent.ProTypeEnum;
import cn.com.surker.lab.dao.LabExpendUploadLineDao;
import cn.com.surker.lab.dao.LabLevelConstructDao;
import cn.com.surker.lab.entity.LabExpendUpload;
import cn.com.surker.lab.entity.LabExpendUploadLine;
import cn.com.surker.lab.entity.LabLevelConstruct;
import cn.com.surker.lab.service.LabExpendUploadLineService;
import cn.com.surker.lab.service.LabExpendUploadService;
import cn.com.surker.lab.service.LabLevelConstructService;
import cn.com.surker.lab.vo.LabExpendUploadLineVo;
import cn.com.surker.lab.vo.LabExpendUploadVo;
import cn.com.surker.production.controller.ProBaseController;
import cn.com.surker.production.entity.vo.ProductionIndentVo;
import cn.com.surker.production.service.ErpIndentService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.system.service.SysLineService;
import cn.com.surker.util.StringUtils;
import cn.com.surker.workcon.common.RecipeTranEntity;
import cn.com.surker.workcon.service.RecipeService;
import cn.com.surker.workcon.service.TaskService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.transaction.RollbackException;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author lucky
 * @create 2024年10月28 16:57
 * @desc 上传配合比控制类
 */
@RestController
@RequestMapping("/lab/expend-upload")
public class LabExpendUploadController extends AbstractController {
    @Value("${erp.datasource.erp.db}")
    protected String erpDb;
    @Value("${erp.datasource.org.name}")
    protected String erpOrgName;
    @Value("${erp.org.id}")
    protected Long orgId;
    @Resource
    private LabExpendUploadLineService labExpendUploadLineService;//上传工控材料明细
    @Resource
    private LabExpendUploadService labExpendUploadService;//上传工控记录

	@Autowired
	private LabLevelConstructService levelConstructService;
	@Resource
	private ErpIndentService indentService;
	@Resource
	private StrengthBaseService strengthService;

	@Autowired
	private SysLineService lineService;

	//	上传工控机的配合比
	@Resource
	private RecipeService recipeService;
	//	工控机的任务单
	@Autowired
	private TaskService taskService;



    /**
     * 分页查询上传任务单配合比信息
     * @param searchVal
     * @param startTime
     * @param endTime
     * @param proType
     * @param isUpload
     * @param page
     * @param limit
     * @param curr
     * @param castType
     * @return
     */
    @RequestMapping(value = "/page", method = RequestMethod.POST)
    public RestResultDto page(String searchVal, String startTime, String endTime, Integer proType,
                              Integer castType, Long strengthId, Integer isUpload, Integer page, Integer limit, Integer curr) {
        try {
            /**分页对象**/
            if (!StringUtils.isNull(curr))//layui不能用page传页码数则修改默认页码参数传入
                page = curr;
            else {
                if (StringUtils.isNull(page))
                    page = 1;
            }
            if (StringUtils.isNull(page))
                page = 1;
            if (StringUtils.isNull(limit))
                limit = 15;
            IPage iPage = labExpendUploadService.findByIndentPage(searchVal, startTime, endTime, proType, castType, isUpload, strengthId, (page - 1) * limit, limit);
            return RestResultDto.success(iPage);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }

    /**
     * 查询任务单上传记录
     * @param indentId
     * @return
     */
    @RequestMapping(value = "/find-indent", method = RequestMethod.POST)
    public RestResultDto findIndent(Long indentId) {
        try {
            List<Map<String, Object>> list = labExpendUploadService.findByIndent(erpDb, indentId);
            if (list == null)
                return RestResultDto.fail("未获取到上传工控的记录数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }

    /**
     * 根据任务单ID查询上传记录
     * @param indentId
     * @return
     */
    @RequestMapping(value = "/find-history", method = RequestMethod.POST)
    public RestResultDto findHistory(Long indentId) {
        try {
            List<LabExpendUploadVo> list = labExpendUploadService.findIndentHistory(erpDb,indentId);
            if (list == null)
                return RestResultDto.fail("未获取到上传工控的记录数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 根据配比材料记录
     * @param uploadId
     * @return
     */
    @RequestMapping(value = "/find-material", method = RequestMethod.POST)
    public RestResultDto findMaterial(Long uploadId) {
        try {
            List<LabExpendUploadLineVo> list = labExpendUploadLineService.findExpendUploadList(uploadId);
            if (list == null)
                return RestResultDto.fail("未获取到配比材料记录数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 查询上传工控配合比记录
     * @param id 任务单ID
     * @param uploadLine 生产线id
     * @param lineCode 生产线code
     * @param isUpload 是否上传状态
     * @return
     */
    @RequestMapping(value = "/find-upload", method = RequestMethod.POST)
    public RestResultDto findUploadData(Long id, String uploadLine, String lineCode, String isUpload) {
        try {
            List<Map<String, Object>> list = labExpendUploadService.findUploadData(id, uploadLine, lineCode, isUpload);
            if (list == null)
                return RestResultDto.fail("未获取到上传工控的记录数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 查询上传工控的材料数据
     * @param uploadId
     * @return
     */
    @RequestMapping(value = "/find-expend", method = RequestMethod.POST)
    public RestResultDto findExpend(Long uploadId) {
        try {
            List<LabExpendUploadLine> list = labExpendUploadLineService.findByPId(uploadId);
            if (list == null)
                return RestResultDto.fail("未获取到上传工控的材料数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 查询上传工控的材料数据
     * @param constructId
     * @return
     */
    @RequestMapping(value = "/find-construct", method = RequestMethod.POST)
    public RestResultDto findConstruct(Long constructId) {
        try {
            List<LabExpendUploadLine> list = labExpendUploadLineService.findByConstruct(constructId);
            if (list == null)
                return RestResultDto.fail("未获取到上传工控的材料数据");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }

    /**
     * 查询标号历史配比
     * @return
     */
    @RequestMapping(value = "/find-history-v1", method = RequestMethod.POST)
    public RestResultDto findStrengthHistory(Long lineId, Long strengthId) {
        try {
            List<LabExpendUploadVo> list = labExpendUploadService.findStrengthHistory(erpDb, lineId, strengthId);
            if (list == null)
                return RestResultDto.fail("未获取到历史上传配比");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 保存上传配合比记录
     * @param expendUpload
     * @param results
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.PUT)
    @Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
    public RestResultDto save(@Validated @RequestBody LabExpendUpload expendUpload, BindingResult results) {
        try {
            if (results.hasErrors()) {
                String defaultMessage = results.getFieldError().getDefaultMessage();
                return RestResultDto.fail(defaultMessage);
            }
            if (expendUpload.getList() == null || expendUpload.getList().size() == 0)
                return RestResultDto.fail("配合比材料子项不能为空");
            List<LabExpendUploadLine> list = expendUpload.getList();
            CacheUser user = getUser();
            expendUpload.setCreator(user.getName());
            RestResultDto dto = labExpendUploadService.saveUpload(expendUpload);
            if (dto.getCode() != 0)
                return dto;
            LabExpendUpload construct = (LabExpendUpload) dto.getData();

            return labExpendUploadLineService.saveBatchLine(construct, list);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 保存并上传配合比记录
     */
    @RequestMapping(value = "/save-v1", method = RequestMethod.PUT)
    @Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto saveV1(@Validated @RequestBody LabExpendUpload expendUploadParam, BindingResult results) {
        try {
            if (results.hasErrors()) {
                String defaultMessage = results.getFieldError().getDefaultMessage();
                return RestResultDto.fail(defaultMessage);
            }
			if (expendUploadParam.getList() == null || expendUploadParam.getList().size() == 0)
                return RestResultDto.fail("配合比材料子项不能为空");
			List<LabExpendUploadLine> list = expendUploadParam.getList();
			//	登录用户
            CacheUser user = getUser();
			//	当前时间
			Date nowDate = new Date();
			expendUploadParam.setCreator(user.getName());
			//	设置已经上传
			expendUploadParam.setIsUpload(UploadTypeEnum.DONE.getCode());
			expendUploadParam.setCreateTime(nowDate);
			RestResultDto dto = labExpendUploadService.saveUpload(expendUploadParam);
			if (dto.getCode() != 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return dto;
			}
            LabExpendUpload construct = (LabExpendUpload) dto.getData();
            dto = labExpendUploadLineService.saveBatchLine(construct, list);
			if (dto.getCode() != 0) {
				//	回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return dto;
			}
			//	上传配合比ID
			Long expendUploadId = expendUploadParam.getId();
			if (expendUploadId == null) {
				throw new MessageCenterException("参数错误");
			}
			//	查询数据		TODO 此处是否可以用前面的数据,减少一次查询?
			LabExpendUpload labExpendUpload = labExpendUploadService.getById(expendUploadId);
			RestResultDto restResultDto = uploadLine(labExpendUpload, nowDate);
			//	提交事务
			taskService.commitTranAll();
			return restResultDto;
			//	原来直接上传的方法 labExpendUploadLineService.uploadLine(expendUploadId);
			//	现在改为v2
			// RestResultDto ulRes = labExpendUploadLineService.uploadLine(expendUploadId);
			// return ulRes;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			taskService.rollbackAll();
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 验证集中上传配合比是否保存
     */
    @RequestMapping(value = "/find-batch-line", method = RequestMethod.POST)
    public RestResultDto findIndentOrLine(Long indentId, String lineIds) {
        try {
            List<LabExpendUpload> list = labExpendUploadService.findIndentOrLine(erpDb, indentId, lineIds);
            if (list == null)
                return RestResultDto.fail("选中生产线未保存配合比信息");
            String[] lineIds_ = lineIds.split(",");
            List<Long> lines = new ArrayList<>();
            for (int i = 0; i <lineIds_.length; i++) {
                lines.add(StringUtils.convertLong(lineIds_[i]));
            }
            List<Long> uploadLines = new ArrayList<>();
            for (LabExpendUpload upload : list) {
                Long lineId = upload.getUploadLine();
                uploadLines.add(lineId);

            }
            for (Long lineId : lines) {
                if (!uploadLines.contains(lineId))
                    return RestResultDto.success("标识" + lineId + "线的配合比信息未保存");
            }
            if (lineIds_.length != list.size())
                return RestResultDto.fail("存在未保存的配比信息,请检查配合比是否均已保存~！");
            return RestResultDto.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 保存上传工控
     */
    @RequestMapping(value = "/upload-batch", method = RequestMethod.PUT)
    @Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
    public RestResultDto uploadBatch(Long indentId, String lineIds,String uploadIndentIds) {
        try {
            CacheUser user = getUser();
            List<LabExpendUpload> uploadList = labExpendUploadService.saveBatchUpload(erpDb, indentId, lineIds, orgId, uploadIndentIds, orgName, user.getName());
            if (uploadList == null || uploadList.size() == 0)
                return RestResultDto.fail("没有需要上传的配合比");
            Date nowDate = new Date();
            for (LabExpendUpload expendUpload : uploadList) {
                uploadLine(expendUpload, nowDate);
            }
            taskService.commitTranAll();
            return RestResultDto.success("上传成功");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            taskService.rollbackAll();
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }
    /**
     * 保存上传工控
     */
    @RequestMapping(value = "/save-plc/{id}", method = RequestMethod.PUT)
    @Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
    public RestResultDto savePlc(@PathVariable Long id) {
        try {
			// RestResultDto ulRes = labExpendUploadLineService.uploadLine(id);
            CacheUser user = getUser();
			LabExpendUpload expendUpload = labExpendUploadService.getById(id);
            expendUpload.setUpdator(user.getName());
			RestResultDto ulRes = uploadLine(expendUpload, new Date());
			taskService.commitTranAll();
			return ulRes;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			taskService.rollbackAll();
            e.printStackTrace();
            return RestResultDto.fail(e.getMessage());
        }
    }

	/**
	 * 上传生产线
	 */
	private RestResultDto uploadLine(LabExpendUpload labExpendUpload, Date nowDate) {
		if (labExpendUpload == null || !StateEnum.ENABLED.getCode().equals(labExpendUpload.getStatus())) {
			throw new MessageCenterException("工控配合比记录不存在或已被禁用");
		}
		Long expendUploadId = labExpendUpload.getId();
		//	取出任务单id
		Long indentId = labExpendUpload.getIndentId();
		if (indentId == null) {
			throw new MessageCenterException("任务单信息为空");
		}
		//	查询任务单
		ProductionIndentVo indentVo = indentService.queryFullById(erpDb, indentId);
		if (indentVo == null || !StateEnum.ENABLED.getCode().equals(indentVo.getStatus()) || ProTypeEnum.END.getCode().equals(indentVo.getType())) {
			throw new MessageCenterException("任务单不存在或已被禁用、供毕");
		}
		// 查询生产线
		Long lineId = labExpendUpload.getUploadLine();
		//	生产线数据
		SysLine line = lineService.getById(lineId);
		if (line == null || !StateEnum.ENABLED.getCode().equals(line.getStatus())) {
			throw new MessageCenterException("生产线不存在或已被删除");
		}
		Long strengthId = indentVo.getStrengthId();
		BaseStrength baseStrength = strengthService.getById(strengthId);
		if (baseStrength == null || baseStrength.getStatus() == 1) {
			throw new MessageCenterException("强度等级不存在或已被禁用、供毕");
		}
		if (StringUtils.isNull(baseStrength.getStrength())) {
			throw new MessageCenterException("强度等级名称错误");
		}
		List<LabExpendUploadLineVo> uploadLines = labExpendUploadLineService.findExpendUploadList(expendUploadId);
		if (uploadLines == null || uploadLines.size() == 0) {
			throw new MessageCenterException("配合比材料明细为空");
		}
		List<RecipeTranEntity> recipeList = convertList2(uploadLines);
		String flag = "14";//砼、砂浆标识 1代表砼 14代表砂浆
		String strengthLevel = baseStrength.getStrength();
		if (strengthLevel.indexOf("C") == 0 || strengthLevel.indexOf("LC") == 0) {
			flag = "1";
		}
		Integer total = labExpendUploadLineService.findExistSn(orgId, SysMaterialTypeEnum.SN.getCode(), expendUploadId);
		if (flag.equals("1") && total < 1) {
			throw new MessageCenterException("配合比材料明细中未包含水泥");
		}
		Integer snDosage = labExpendUploadLineService.findExistSnDosage(orgId, SysMaterialTypeEnum.SN.getCode(), expendUploadId);
		if (flag.equals("1") && snDosage < 1) {
			throw new MessageCenterException("配合比材料明细中水泥用量小于1公斤");
		}
		LabLevelConstruct levelConstruct = levelConstructService.getById(labExpendUpload.getLabLevelConstructId());
		String scale = "";//设计比例
		if (levelConstruct != null) {
			scale = levelConstruct.getMixRatio();
		}
		//	上传任务单
		List<LabExpendUpload> expendUploadList = new ArrayList<>();
		expendUploadList.add(labExpendUpload);
		indentVo.setExpendUploadLines(expendUploadList);
		int insert = taskService.insert(lineId, indentVo, nowDate);
		if (insert < 0) {
			//	回滚数据
			throw new MessageCenterException("上传工控机任务单失败");
		}
		//	上传配合比
		Long taskId = recipeService.uploadExpend(line, indentVo, labExpendUpload.getCode(), baseStrength.getStrength(), "", "", "", labExpendUpload.getMixTime(), scale,
			"", "", recipeList, nowDate);
		if (taskId != null && taskId > 0) {
			//	更新上传工控机的配合比
			labExpendUpload.setControlUploadId(taskId);
            labExpendUpload.setIsUpload(UploadTypeEnum.DONE.getCode());
            labExpendUpload.setUpdateTime(nowDate);
			labExpendUploadService.updateById(labExpendUpload);
			String message = "上传成功";
			if (flag.equals("14") && total < 1) {
				message += ",且配合比材料明细中未包含水泥。";
			}
			if (flag.equals("14") && snDosage < 1) {
				message += ",配合比材料明细中水泥用量小于1公斤。";
			}
			return RestResultDto.success(message);
		} else {
			throw new MessageCenterException("上传工控机配合比失败");
		}
	}

	private List<RecipeTranEntity> convertList2(List<LabExpendUploadLineVo> uploadLines) {
		List<RecipeTranEntity> list = new ArrayList<>();
		for (int i = 0; i < uploadLines.size(); i++) {
			LabExpendUploadLineVo line = uploadLines.get(i);
			if (StringUtils.isNull(line.getMaterialName()) || line.getRealDosage() < 0)
				continue;
			RecipeTranEntity recipeTranEntity = new RecipeTranEntity();
			recipeTranEntity.setMaterialId(line.getMaterialId());
			recipeTranEntity.setControlStorageId(line.getControlStorageId());
			recipeTranEntity.setMaterialType(line.getMaterialType());
			recipeTranEntity.setErpStorageId(line.getErpStorageId());
			recipeTranEntity.setControlMaterial(line.getControlMaterial());
			recipeTranEntity.setControlStorage(line.getControlStorage());
			recipeTranEntity.setConcreteDosage(line.getRealDosage());
			recipeTranEntity.setStandDosage(line.getStandNum());
			list.add(recipeTranEntity);
		}
		return list;
	}

}
